package com.qcby.service.impl;

import com.qcby.service.DeepSeekService;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
public class DeepSeekServiceImpl implements DeepSeekService {
    private static final Logger logger = LoggerFactory.getLogger(DeepSeekServiceImpl.class);

    private static final String API_KEY = "Bearer sk-56169048534f4fb5aab3bd54a1c56a54";
    private static final String API_URL = "https://api.deepseek.com/chat/completions";
    private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");

    // 使用单例OkHttpClient（推荐）
    private static final OkHttpClient httpClient = new OkHttpClient.Builder()
            .connectTimeout(120, TimeUnit.SECONDS)
            .readTimeout(120, TimeUnit.SECONDS)
            .writeTimeout(120, TimeUnit.SECONDS)
            .addInterceptor(new RetryInterceptor(3)) // 重试3次
            .addInterceptor(new LoggingInterceptor()) // 自定义日志
            .build();

    @Override
    public String getJson(String context) throws IOException {
        String jsonBody = buildRequestBody(context);
        logger.debug("Sending request to DeepSeek API: {}", jsonBody);
        RequestBody body = RequestBody.create(MediaType.get("application/json"),jsonBody);
        Request request = new Request.Builder()
                .url(API_URL)
                .post(body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Accept", "application/json")
                .addHeader("Authorization", API_KEY)
                .build();

        try (Response response = httpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                String errorBody = response.body() != null ? response.body().string() : "null";
                logger.error("API request failed with code: {}, body: {}", response.code(), errorBody);
                throw new IOException("API request failed: " + response.code());
            }
            return response.body().string();
        } catch (IOException e) {
            logger.error("Failed to call DeepSeek API", e);
            throw e;
        }
    }

    // 构建请求体（JSON格式化）
    private String buildRequestBody(String context) {
        return String.format("{\n"
                + "  \"model\": \"deepseek-chat\",\n"
                + "  \"messages\": [\n"
                + "    {\"role\": \"user\", \"content\": \"%s\"}\n"
                + "  ],\n"
                + "  \"temperature\": 0.7,\n"
                + "  \"top_p\": 0.8\n"
                + "}", escapeJson(context));
    }

    // 简单JSON转义（防止注入）
    private String escapeJson(String input) {
        return input.replace("\"", "\\\"")
                .replace("\n", "\\n")
                .replace("\r", "\\r");
    }

    // 自定义重试拦截器
    static class RetryInterceptor implements Interceptor {
        private final int maxRetries;

        public RetryInterceptor(int maxRetries) {
            this.maxRetries = maxRetries;
        }

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            IOException lastException = null;

            for (int i = 0; i <= maxRetries; i++) {
                try {
                    Response response = chain.proceed(request);
                    if (response.isSuccessful() || i == maxRetries) {
                        return response;
                    }
                } catch (IOException e) {
                    lastException = e;
                    if (i == maxRetries) throw lastException;
                }

                try {
                    Thread.sleep(1000 * (i + 1)); // 递增延迟 (1s, 2s, 3s...)
                } catch (InterruptedException ignored) {}
            }
            throw lastException;
        }
    }

    // 自定义日志拦截器
    static class LoggingInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            long startTime = System.nanoTime();

            logger.info("--> Sending {} request to {}", request.method(), request.url());
            if (logger.isDebugEnabled()) {
                logger.debug("Headers: {}", request.headers());
            }

            Response response = chain.proceed(request);
            long duration = (System.nanoTime() - startTime) / 1_000_000;

            logger.info("<-- Received response in {}ms (code: {})", duration, response.code());
            return response;
        }
    }
}